/**
 * 波浪形频谱可视化器
 */
class WaveSpectrumVisualizer extends VisualizerInterface {
    constructor(canvas, ctx) {
        super(canvas, ctx);
        this.waveHistory = [];
        this.particles = [];
        this.currentWave = [];
    }

    getInfo() {
        return {
            name: 'Wave Spectrum',
            description: '流动波浪形频谱可视化',
            author: 'AudioNN',
            version: '1.0.0',
            category: 'wave'
        };
    }

    getDefaultSettings() {
        return {
            ...super.getDefaultSettings(),
            waveCount: 3,
            waveSpeed: 2,
            waveAmplitude: 0.8,
            flowDirection: 'right', // left, right, up, down
            particleCount: 50,
            showParticles: true,
            showMirror: true,
            lineThickness: 3,
            fillWave: true,
            smoothing: 0.8
        };
    }

    getConfigurableParams() {
        return [
            ...super.getConfigurableParams(),
            {
                key: 'waveCount',
                label: '波浪层数',
                type: 'range',
                min: 1,
                max: 5,
                step: 1,
                default: 3
            },
            {
                key: 'waveSpeed',
                label: '波浪速度',
                type: 'range',
                min: 0.5,
                max: 5,
                step: 0.5,
                default: 2
            },
            {
                key: 'waveAmplitude',
                label: '波浪幅度',
                type: 'range',
                min: 0.3,
                max: 1.5,
                step: 0.1,
                default: 0.8
            },
            {
                key: 'flowDirection',
                label: '流动方向',
                type: 'select',
                options: [
                    { value: 'right', label: '向右' },
                    { value: 'left', label: '向左' },
                    { value: 'up', label: '向上' },
                    { value: 'down', label: '向下' }
                ],
                default: 'right'
            },
            {
                key: 'showParticles',
                label: '显示粒子',
                type: 'boolean',
                default: true
            },
            {
                key: 'showMirror',
                label: '显示镜像',
                type: 'boolean',
                default: true
            },
            {
                key: 'fillWave',
                label: '填充波浪',
                type: 'boolean',
                default: true
            }
        ];
    }

    init(config = {}) {
        super.init(config);
        this.waveOffset = 0;
        this.initializeParticles();
        this.waveHistory = [];
        return this;
    }

    initializeParticles() {
        this.particles = [];
        const width = this.canvas.width / window.devicePixelRatio;
        const height = this.canvas.height / window.devicePixelRatio;
        
        for (let i = 0; i < this.settings.particleCount; i++) {
            this.particles.push({
                x: Math.random() * width,
                y: Math.random() * height,
                vx: (Math.random() - 0.5) * 2,
                vy: (Math.random() - 0.5) * 2,
                size: Math.random() * 3 + 1,
                opacity: Math.random() * 0.5 + 0.5,
                life: Math.random() * 100 + 50,
                maxLife: 150,
                frequency: Math.random()
            });
        }
    }

    render(frequencyData, cachedData = null, currentTime = 0) {
        this.clearCanvas();
        
        const dataToUse = cachedData || frequencyData;
        if (!dataToUse) return;

        const width = this.canvas.width / window.devicePixelRatio;
        const height = this.canvas.height / window.devicePixelRatio;

        // 更新波浪偏移
        this.waveOffset += this.settings.waveSpeed * 0.01;

        // 处理频谱数据
        this.processFrequencyData(dataToUse);

        // 绘制多层波浪
        for (let layer = 0; layer < this.settings.waveCount; layer++) {
            this.drawWaveLayer(dataToUse, layer, width, height);
        }

        // 绘制镜像效果
        if (this.settings.showMirror) {
            this.drawMirrorEffect(width, height);
        }

        // 绘制粒子
        if (this.settings.showParticles) {
            this.updateAndDrawParticles(dataToUse, width, height);
        }

        // 绘制频谱信息
        this.drawSpectrumInfo(dataToUse, width, height);
    }

    processFrequencyData(frequencyData) {
        // 对频谱数据进行平滑处理
        if (this.currentWave.length === 0) {
            this.currentWave = Array.from(frequencyData);
        } else {
            for (let i = 0; i < frequencyData.length; i++) {
                this.currentWave[i] = this.currentWave[i] * this.settings.smoothing + 
                                   frequencyData[i] * (1 - this.settings.smoothing);
            }
        }

        // 保存波浪历史记录（用于流动效果）
        this.waveHistory.unshift([...this.currentWave]);
        if (this.waveHistory.length > 50) {
            this.waveHistory.pop();
        }
    }

    drawWaveLayer(frequencyData, layer, width, height) {
        const layerOffset = layer * 0.3;
        const layerAlpha = 1 - layer * 0.2;
        const layerAmplitude = this.settings.waveAmplitude * (1 - layer * 0.15);
        
        // 根据流动方向选择绘制方式
        if (this.settings.flowDirection === 'right' || this.settings.flowDirection === 'left') {
            this.drawHorizontalWave(frequencyData, layer, layerOffset, layerAlpha, layerAmplitude, width, height);
        } else {
            this.drawVerticalWave(frequencyData, layer, layerOffset, layerAlpha, layerAmplitude, width, height);
        }
    }

    drawHorizontalWave(frequencyData, layer, layerOffset, layerAlpha, layerAmplitude, width, height) {
        const centerY = height / 2;
        const points = 256; // 控制波浪的精细度
        const step = width / points;
        
        // 创建路径
        this.ctx.beginPath();
        
        for (let i = 0; i <= points; i++) {
            const x = i * step;
            const dataIndex = Math.floor((i / points) * frequencyData.length);
            const amplitude = (frequencyData[dataIndex] / 255) * layerAmplitude * height * 0.3;
            
            // 添加波浪效果
            const waveEffect = Math.sin((x * 0.01 + this.waveOffset + layerOffset) * Math.PI) * 20;
            const flowOffset = this.getFlowOffset(layer);
            
            const y = centerY - amplitude + waveEffect + flowOffset * layer * 10;
            
            if (i === 0) {
                this.ctx.moveTo(x, y);
            } else {
                this.ctx.lineTo(x, y);
            }
        }

        // 绘制填充波浪
        if (this.settings.fillWave) {
            // 完成填充路径
            this.ctx.lineTo(width, centerY);
            this.ctx.lineTo(0, centerY);
            this.ctx.closePath();
            
            // 创建渐变填充
            const gradient = this.ctx.createLinearGradient(0, 0, 0, height);
            const baseColor = this.getLayerColor(layer, 1); // 获取不透明颜色
            const rgb = baseColor.match(/\d+/g); // 提取RGB值
            gradient.addColorStop(0, `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${layerAlpha * 0.3})`);
            gradient.addColorStop(1, `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0)`);
            
            this.ctx.fillStyle = gradient;
            this.ctx.fill();
        }

        // 绘制波浪线条
        this.ctx.strokeStyle = this.getLayerColor(layer, layerAlpha);
        this.ctx.lineWidth = this.settings.lineThickness;
        this.ctx.stroke();

        // 添加发光效果
        this.ctx.shadowColor = this.getLayerColor(layer, 1);
        this.ctx.shadowBlur = 10;
        this.ctx.stroke();
        this.ctx.shadowBlur = 0;
    }

    drawVerticalWave(frequencyData, layer, layerOffset, layerAlpha, layerAmplitude, width, height) {
        const centerX = width / 2;
        const points = 256;
        const step = height / points;
        
        this.ctx.beginPath();
        
        for (let i = 0; i <= points; i++) {
            const y = i * step;
            const dataIndex = Math.floor((i / points) * frequencyData.length);
            const amplitude = (frequencyData[dataIndex] / 255) * layerAmplitude * width * 0.3;
            
            const waveEffect = Math.sin((y * 0.01 + this.waveOffset + layerOffset) * Math.PI) * 20;
            const flowOffset = this.getFlowOffset(layer);
            
            const x = centerX - amplitude + waveEffect + flowOffset * layer * 10;
            
            if (i === 0) {
                this.ctx.moveTo(x, y);
            } else {
                this.ctx.lineTo(x, y);
            }
        }

        if (this.settings.fillWave) {
            this.ctx.lineTo(centerX, height);
            this.ctx.lineTo(centerX, 0);
            this.ctx.closePath();
            
            const gradient = this.ctx.createLinearGradient(0, 0, width, 0);
            const baseColor = this.getLayerColor(layer, 1); // 获取不透明颜色
            const rgb = baseColor.match(/\d+/g); // 提取RGB值
            gradient.addColorStop(0, `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${layerAlpha * 0.3})`);
            gradient.addColorStop(1, `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, 0)`);
            
            this.ctx.fillStyle = gradient;
            this.ctx.fill();
        }

        this.ctx.strokeStyle = this.getLayerColor(layer, layerAlpha);
        this.ctx.lineWidth = this.settings.lineThickness;
        this.ctx.stroke();
        
        this.ctx.shadowColor = this.getLayerColor(layer, 1);
        this.ctx.shadowBlur = 10;
        this.ctx.stroke();
        this.ctx.shadowBlur = 0;
    }

    getFlowOffset(layer) {
        const direction = this.settings.flowDirection;
        const speed = this.settings.waveSpeed * 0.1;
        
        switch (direction) {
            case 'right':
                return Math.sin(this.waveOffset * speed);
            case 'left':
                return -Math.sin(this.waveOffset * speed);
            case 'up':
                return -Math.cos(this.waveOffset * speed);
            case 'down':
                return Math.cos(this.waveOffset * speed);
            default:
                return 0;
        }
    }

    getLayerColor(layer, alpha) {
        const hue = (layer * 60 + this.waveOffset * 10) % 360;
        const saturation = 80;
        const lightness = 60 - layer * 10;
        
        const rgb = this.hslToRgb(hue, saturation, lightness);
        return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${alpha})`;
    }

    drawMirrorEffect(width, height) {
        // 绘制水面镜像效果
        this.ctx.save();
        
        // 设置镜像变换
        this.ctx.scale(1, -1);
        this.ctx.translate(0, -height);
        
        // 绘制半透明的镜像
        this.ctx.globalAlpha = 0.3;
        
        // 创建渐变遮罩
        const gradient = this.ctx.createLinearGradient(0, height / 2, 0, height);
        gradient.addColorStop(0, 'rgba(0, 0, 0, 0.5)');
        gradient.addColorStop(1, 'rgba(0, 0, 0, 1)');
        
        this.ctx.fillStyle = gradient;
        this.ctx.fillRect(0, height / 2, width, height / 2);
        
        this.ctx.restore();
    }

    updateAndDrawParticles(frequencyData, width, height) {
        // 计算平均强度
        const avgIntensity = frequencyData.reduce((sum, val) => sum + val, 0) / frequencyData.length / 255;
        
        this.particles.forEach((particle, index) => {
            // 根据音频强度更新粒子
            const frequencyIndex = Math.floor(particle.frequency * frequencyData.length);
            const localIntensity = frequencyData[frequencyIndex] / 255;
            
            // 更新粒子位置
            particle.x += particle.vx * (1 + localIntensity);
            particle.y += particle.vy * (1 + localIntensity);
            
            // 边界处理
            if (particle.x < 0 || particle.x > width) particle.vx = -particle.vx;
            if (particle.y < 0 || particle.y > height) particle.vy = -particle.vy;
            
            // 生命周期
            particle.life--;
            if (particle.life <= 0) {
                particle.life = particle.maxLife;
                particle.x = Math.random() * width;
                particle.y = Math.random() * height;
            }
            
            // 绘制粒子
            const alpha = (particle.life / particle.maxLife) * particle.opacity * localIntensity;
            if (alpha > 0.1) {
                this.ctx.fillStyle = `rgba(255, 255, 255, ${alpha})`;
                this.ctx.beginPath();
                this.ctx.arc(particle.x, particle.y, particle.size * (1 + localIntensity), 0, Math.PI * 2);
                this.ctx.fill();
                
                // 添加发光效果
                this.ctx.shadowColor = 'white';
                this.ctx.shadowBlur = localIntensity * 10;
                this.ctx.fill();
                this.ctx.shadowBlur = 0;
            }
        });
    }

    drawSpectrumInfo(frequencyData, width, height) {
        // 绘制频谱信息条
        const barCount = 32;
        const barWidth = width / barCount;
        const maxBarHeight = 60;
        
        for (let i = 0; i < barCount; i++) {
            const dataIndex = Math.floor((i / barCount) * frequencyData.length);
            const intensity = frequencyData[dataIndex] / 255;
            const barHeight = intensity * maxBarHeight;
            
            // 根据层级位置绘制频谱条
            const x = i * barWidth;
            const y = height - barHeight - 10;
            
            const hue = (i / barCount) * 360;
            const color = this.hslToRgb(hue, 80, 60);
            
            this.ctx.fillStyle = `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${intensity})`;
            this.ctx.fillRect(x, y, barWidth - 2, barHeight);
            
            // 添加发光效果
            if (intensity > 0.3) {
                this.ctx.shadowColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
                this.ctx.shadowBlur = intensity * 15;
                this.ctx.fillRect(x, y, barWidth - 2, barHeight);
                this.ctx.shadowBlur = 0;
            }
        }
    }

    resize(width, height) {
        this.initializeParticles();
        this.waveHistory = [];
    }
}

// 注册可视化器到全局注册表
if (typeof window !== 'undefined') {
    if (!window.visualizerRegistrations) {
        window.visualizerRegistrations = [];
    }
    window.visualizerRegistrations.push({
        id: 'wave-spectrum',
        class: WaveSpectrumVisualizer
    });
}

window.WaveSpectrumVisualizer = WaveSpectrumVisualizer;
